package com.sumer.design.singleton;

/**
 * 懒汉式
 * 优点：
 * 缺点：
 */
public class LazyMan {

    private LazyMan() {
        System.out.println("我被实例化了");
    }

    private volatile static LazyMan INSTANCE;

    public static LazyMan getInstance() {
        if (INSTANCE == null) {
            INSTANCE = new LazyMan();
        }
        return INSTANCE;
    }

    // 双重校测锁模式
    public static LazyMan getInstance1() {
        if (INSTANCE == null) {
            synchronized (LazyMan.class) {
                if (INSTANCE == null) {
                    /**
                     * 这里不是原子操作
                     * 1.分配内存空间
                     * 2.初始化对象
                     * 3.把这个对象指向这个空间
                     * jvm可能对这几步进行指令重排
                     * 比如说：顺序是1 3 2 当还没有完成初始化的时候，另一个线程进来判断INSTANCE是部位空的，就返回了。
                     */
                    INSTANCE = new LazyMan();
                }
            }
        }
        return INSTANCE;
    }

    // 多线程并发测试
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                LazyMan.getInstance();
            }).start();
        }
    }
}
